#include "PosixTestClient.h"

#include "EPosixClientSocket.h"
#include "EPosixClientSocketPlatform.h"

#include "Contract.h"
#include "Order.h"
#include <iostream>
#include <string>
#include <windows.h>
#include <winbase.h>

#ifdef _WIN32
# include <Windows.h>
# define sleep( seconds) Sleep( seconds * 1000);
#else
# include <unistd.h>
#endif

const int PING_DEADLINE = 2; // seconds
const int SLEEP_BETWEEN_PINGS = 30; // seconds

///////////////////////////////////////////////////////////
// member funcs

void PosixTestClient::tickPrice( TickerId tickerId, TickType field, double price, int canAutoExecute) {
	std::string type;
//-----------Handleing update on Dell and AMD quote change -------------------
	PosixTestClient::PrintAllParams();

	std::cout<< "tcikPrice Call Back:  TickerID="<< tickerId << "   TickType=" << field << std::endl;
	switch(tickerId) {
		case 100:        //-----handle Dell price update ---------
			if (field == BID) m_PairsTrading_Param.tb=price;
			else if (field == ASK) m_PairsTrading_Param.ta=price;
			else {
	//			m_PairsTrading_Param.ta=price;
	//			m_PairsTrading_Param.tb=price;
			}

		break;
		case 101:        //-----handle AMD price update ---------
			if (field == BID) m_PairsTrading_Param.bb=price;
			else if (field == ASK ) m_PairsTrading_Param.ba=price;
			else {
	//			m_PairsTrading_Param.ba=price;
	//			m_PairsTrading_Param.bb=price;
			}
		default:
		break;
	} 

	std::cout	<< "Quote price update: TickerId=" << tickerId << "\t" 
				<< "TickType=" <<  type << "\t"
				<< "Price=" << price << "\t" 
				<< "canAutoExecute=" << canAutoExecute << std::endl;

	m_PairsTrading_Param.ratio0=(log(m_PairsTrading_Param.tb/m_PairsTrading_Param.ba)-m_PairsTrading_Param.mu)/m_PairsTrading_Param.sigma;
	m_PairsTrading_Param.ratio1=(log(m_PairsTrading_Param.ta/m_PairsTrading_Param.bb)-m_PairsTrading_Param.mu)/m_PairsTrading_Param.sigma;
	m_PairsTrading_Param.ratio0_onOpen=(log(m_PairsTrading_Param.tb/m_PairsTrading_Param.ba)-m_PairsTrading_Param.mu)/m_PairsTrading_Param.sigma;
	m_PairsTrading_Param.ratio1_onOpen=(log(m_PairsTrading_Param.ta/m_PairsTrading_Param.bb)-m_PairsTrading_Param.mu)/m_PairsTrading_Param.sigma;


	m_PairsTrading_Param.ValidateParam();

	if (m_PairsTrading_Param.haveOpenPosition == false) {


	if (m_PairsTrading_Param.readyToTrade == true) {
		if (m_PairsTrading_Param.ratio0 >= m_PairsTrading_Param.highVal) 
			{BuyTopSellBottom_toOpen();}
		else if (m_PairsTrading_Param.ratio1 <= m_PairsTrading_Param.lowVal)
			BuytopSellBottom_toOpen();

	}
	else 
	{
		if (m_PairsTrading_Param.readyToTrade == true) {
	
			if (m_PairsTrading_Param.ratio0 >= m_PairsTrading_Param.buyValM)
				BuytopSellBottom_toClose();
			else if (m_PairsTrading_Param.ratio0_onOpen >= m_PairsTrading_Param.sellValM)
				SelltopBuyBottom_toClose();	
		}
	}	
	}
}



void PosixTestClient::BuyTopSellBottom_toOpen()
{
	std::cout << "SellTopBuyBottom to Open Position..." << std::endl;
	Contract contract1,contract2;
	Order order1,order2;

	contract1.symbol = "DELL";
	contract1.secType = "STK";
	contract1.exchange = "SMART";
	contract1.currency = "USD";
	order1.action = "SELL";
	order1.totalQuantity = int (60.0/m_PairsTrading_Param.tb);
	m_PairsTrading_Param.OpenPosTop=order1.totalQuantity;
	m_PairsTrading_Param.OpenPosTopflag=-1;
	m_PairsTrading_Param.haveOpenPosition = true ;
	order1.orderType = "LMT";
	order1.lmtPrice = m_PairsTrading_Param.tb-0.10;
	printf( "Placing Order %ld: %s %ld %s at %f\n", m_orderId, order1.action.c_str(), 
		order1.totalQuantity, contract1.symbol.c_str(), order1.lmtPrice);
	m_state = ST_PLACEORDER_ACK;
	m_pClient->placeOrder( m_orderId, contract1, order1);

		std::cout << "Buy AMD to Open Position..." << std::endl;

	contract2.symbol = "AMD";
	contract2.secType = "STK";
	contract2.exchange = "SMART";
	contract2.currency = "USD";
	order2.action = "BUY";
	order2.totalQuantity = int(60.0/m_PairsTrading_Param.ba);
	m_PairsTrading_Param.OpenPosBottom=order2.totalQuantity;
	m_PairsTrading_Param.OpenPosTopflag=1;
	m_PairsTrading_Param.haveOpenPosition = true ;
	order2.orderType = "LMT";
	order2.lmtPrice = m_PairsTrading_Param.ba+0.10;
	printf( "Placing Order %ld: %s %ld %s at %f\n", m_orderId, order2.action.c_str(), 
		order2.totalQuantity, contract2.symbol.c_str(), order2.lmtPrice);
	m_state = ST_PLACEORDER_ACK;
	m_pClient->placeOrder( m_orderId, contract2, order2);
	
	
}

void PosixTestClient::BuytopSellBottom_toOpen()
{
	std::cout << "BuyTopSellBottom to Open Position..." << std::endl;
	Contract contract1,contract2;
	Order order1,order2;

	contract1.symbol = "DELL";
	contract1.secType = "STK";
	contract1.exchange = "SMART";
	contract1.currency = "USD";
	order1.action = "BUY";
	order1.totalQuantity = int (60.0/m_PairsTrading_Param.ta);

	m_PairsTrading_Param.OpenPosTop=order1.totalQuantity;
	m_PairsTrading_Param.OpenPosTopflag= -1;
	m_PairsTrading_Param.haveOpenPosition =true;

	order1.orderType = "LMT";
	order1.lmtPrice = m_PairsTrading_Param.ta+0.10;
	printf( "Placing Order %ld: %s %ld %s at %f\n", m_orderId, order1.action.c_str(), 
		order1.totalQuantity, contract1.symbol.c_str(), order1.lmtPrice);
	m_state = ST_PLACEORDER_ACK;
	m_pClient->placeOrder( m_orderId, contract1, order1);
	
	contract2.symbol = "AMD";
	contract2.secType = "STK";
	contract2.exchange = "SMART";
	contract2.currency = "USD";
	order2.action = "SELL";
	order2.totalQuantity = int(60.0/m_PairsTrading_Param.bb);

	m_PairsTrading_Param.OpenPosBottom=order2.totalQuantity;
	m_PairsTrading_Param.OpenPosBottomflag= 1;
	m_PairsTrading_Param.haveOpenPosition =true;

	order2.orderType = "LMT";
	order2.lmtPrice = m_PairsTrading_Param.bb-0.10;
	printf( "Placing Order %ld: %s %ld %s at %f\n", m_orderId, order2.action.c_str(), 
		order2.totalQuantity, contract2.symbol.c_str(), order2.lmtPrice);
	m_state = ST_PLACEORDER_ACK;
	m_pClient->placeOrder( m_orderId, contract2, order2);
}


void PosixTestClient::SelltopBuyBottom_toClose()
{
	std::cout << "SellTopBuyBottom to Close Position..." << std::endl;
	Contract contract1,contract2;
	Order order1,order2;

	contract1.symbol = "DELL";
	contract1.secType = "STK";
	contract1.exchange = "SMART";
	contract1.currency = "USD";
	order1.action = "SELL";
	order1.totalQuantity = m_PairsTrading_Param.OpenPosTop;
	m_PairsTrading_Param.OpenPosTop=0;
	m_PairsTrading_Param.OpenPosTopflag=0;
	m_PairsTrading_Param.haveOpenPosition = false ;
	order1.orderType = "LMT";
	order1.lmtPrice = m_PairsTrading_Param.tb-0.10;
	printf( "Placing Order %ld: %s %ld %s at %f\n", m_orderId, order1.action.c_str(), 
		order1.totalQuantity, contract1.symbol.c_str(), order1.lmtPrice);
	m_state = ST_PLACEORDER_ACK;
	m_pClient->placeOrder( m_orderId, contract1, order1);
	
	contract2.symbol = "AMD";
	contract2.secType = "STK";
	contract2.exchange = "SMART";
	contract2.currency = "USD";
	order2.action = "BUY";
	order2.totalQuantity = m_PairsTrading_Param.OpenPosBottom;
	m_PairsTrading_Param.OpenPosBottom=0;
	m_PairsTrading_Param.OpenPosTopflag=0;
	m_PairsTrading_Param.haveOpenPosition = false ;
	order2.orderType = "LMT";
	order2.lmtPrice = m_PairsTrading_Param.ba+0.10;
	printf( "Placing Order %ld: %s %ld %s at %f\n", m_orderId, order2.action.c_str(), 
		order2.totalQuantity, contract2.symbol.c_str(), order2.lmtPrice);
	m_state = ST_PLACEORDER_ACK;
	m_pClient->placeOrder( m_orderId, contract2, order2);
}

void PosixTestClient::BuytopSellBottom_toClose()
{
	std::cout << "BuyTopSellBottom to Close Position..." << std::endl;
	Contract contract1,contract2;
	Order order1,order2;

	contract1.symbol = "DELL";
	contract1.secType = "STK";
	contract1.exchange = "SMART";
	contract1.currency = "USD";
	order1.action = "BUY";
	order1.totalQuantity = m_PairsTrading_Param.OpenPosTop;
	m_PairsTrading_Param.OpenPosTop=0;
	m_PairsTrading_Param.OpenPosTopflag= 0;
	m_PairsTrading_Param.haveOpenPosition =false;

	order1.orderType = "LMT";
	order1.lmtPrice = m_PairsTrading_Param.ta+0.10;
	printf( "Placing Order %ld: %s %ld %s at %f\n", m_orderId, order1.action.c_str(), 
		order1.totalQuantity, contract1.symbol.c_str(), order1.lmtPrice);
	m_state = ST_PLACEORDER_ACK;
	m_pClient->placeOrder( m_orderId, contract1, order1);
	
	contract2.symbol = "AMD";
	contract2.secType = "STK";
	contract2.exchange = "SMART";
	contract2.currency = "USD";
	order2.action = "SELL";
	order2.totalQuantity = m_PairsTrading_Param.OpenPosBottom;
	m_PairsTrading_Param.OpenPosBottom=order2.totalQuantity;
	m_PairsTrading_Param.OpenPosBottomflag= 0;
	m_PairsTrading_Param.haveOpenPosition =false;

	order2.orderType = "LMT";
	order2.lmtPrice = m_PairsTrading_Param.bb-0.10;
	printf( "Placing Order %ld: %s %ld %s at %f\n", m_orderId, order2.action.c_str(), 
		order2.totalQuantity, contract2.symbol.c_str(), order2.lmtPrice);
	m_state = ST_PLACEORDER_ACK;
	m_pClient->placeOrder( m_orderId, contract2, order2);
}

void PosixTestClient::PrintAllParams()
{//---------Print status of all pairs trading parameters--------------
	std::cout << "------------------Pairs Trading Parameters------------------" << std::endl;
	std::cout << "m_PairsTrading_Param.haveOpenPosition	=" << m_PairsTrading_Param.haveOpenPosition << std::endl;
	std::cout << "Bm_PairsTrading_Param.readyToTrade	=" << m_PairsTrading_Param.readyToTrade << std::endl;
	std::cout << "m_PairsTrading_Param.ta				=" << m_PairsTrading_Param.ta << std::endl;
	std::cout << "m_PairsTrading_Param.tb				=" << m_PairsTrading_Param.tb << std::endl;
	std::cout << "m_PairsTrading_Param.ba				=" << m_PairsTrading_Param.ba << std::endl;
	std::cout << "m_PairsTrading_Param.bb				=" << m_PairsTrading_Param.bb << std::endl;
	std::cout << "m_PairsTrading_Param.ratio0			=" << m_PairsTrading_Param.ratio0 << std::endl;
	std::cout << "m_PairsTrading_Param.ratio1			=" << m_PairsTrading_Param.ratio1 << std::endl;
	std::cout << "m_PairsTrading_Param.ratio0_onOpen	=" << m_PairsTrading_Param.ratio0_onOpen << std::endl;
	std::cout << "m_PairsTrading_Param.ratio1_onOpen	=" << m_PairsTrading_Param.ratio1_onOpen << std::endl;
	std::cout << "m_PairsTrading_Param.OpenPosTop		=" << m_PairsTrading_Param.OpenPosTop << std::endl;
	std::cout << "m_PairsTrading_Param.OpenPosTopflag	=" << m_PairsTrading_Param.OpenPosTopflag << std::endl;
	std::cout << "m_PairsTrading_Param.OpenPosBottom	=" << m_PairsTrading_Param.OpenPosBottom << std::endl;
	std::cout << "m_PairsTrading_Param.OpenPosBottomflag=" << m_PairsTrading_Param.OpenPosBottomflag << std::endl;
	std::cout << "-------------------------------------------------------" << std::endl<< std::endl<< std::endl;

}







void PosixTestClient::iniPairsTrading()
{//-------- Various initializlation tarsks for pairs trading------
			std::cout << "Initializing pairs trading" << std::endl;
	reqHistoricalDataDell();
	reqHistoricalDataAMD();

}

void PosixTestClient::historicalData(TickerId reqId, const IBString& date, double open, double high,
									  double low, double close, int volume, int barCount, double WAP, int hasGaps) {
//			std::cout << "Handle historical data " << std::endl;
//	  Since the parameter for historical mean is given, this is not handled her
	std::cout << "historicalData CallBack: ReqID=" << reqId << "\t" << date << "\t" << "Open=" << open << "\t" << "WAP=" << WAP << std::endl;
}




//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------

void PosixTestClient::reqHistoricalDataAMD()
{
	
	Contract contract;
	Order order;

	long int orderId=101;

	contract.symbol = "AMD";
	contract.secType = "STK";
	contract.exchange = "SMART";
	contract.currency = "USD";
	std::cout << "reqHistoricalDataAMD callback::  Requesting historical data for AMD" << std::endl;

	m_pClient->reqHistoricalData(	orderId,				// a long int
									contract,				// a Contract object
									"201103023 00:00:00",	// a string in the format shown
									"6 W",					// a string saying how far back in time you want data
									"1 day",				// the bar size, i.e., how big a time chunk
									"BID",				    // can also be bids, asks, volatility, other stuff
									1,						// 1="useRTH", other possibilities available
									1						// date format; 1=a standard date string 
								);
}


void PosixTestClient::reqHistoricalDataDell()
{
	Contract contract;
	Order order;

	long int orderId=100;

	contract.symbol = "DELL";
	contract.secType = "STK";
	contract.exchange = "SMART";
	contract.currency = "USD";
	std::cout << "reqHistoricalDataDell callback:: Requesting historical data for DELL" << std::endl;

	m_pClient->reqHistoricalData(	orderId,				// a long int
									contract,				// a Contract object
									"20110323 00:00:00",	// a string in the format shown
									"6 W",					// a string saying how far back in time you want data
									"1 day",				// the bar size, i.e., how big a time chunk
									"BID",				    // can also be bids, asks, volatility, other stuff
									1,						// 1="useRTH", other possibilities available
									1						// date format; 1=a standard date string 
								);
	
}




PosixTestClient::PosixTestClient()
	: m_pClient(new EPosixClientSocket(this))
	, m_state(ST_CONNECT)
	, m_sleepDeadline(0)
	, m_orderId(0)
{
}

PosixTestClient::~PosixTestClient()
{
}

bool PosixTestClient::connect(const char *host, unsigned int port, int clientId)
{
	// trying to connect
	printf( "Connecting to %s:%d clientId:%d\n", !( host && *host) ? "127.0.0.1" : host, port, clientId);

	bool bRes = m_pClient->eConnect( host, port, clientId);

	if (bRes) {
		printf( "Connected to %s:%d clientId:%d\n", !( host && *host) ? "127.0.0.1" : host, port, clientId);
	}
	else
		printf( "Cannot connect to %s:%d clientId:%d\n", !( host && *host) ? "127.0.0.1" : host, port, clientId);

	return bRes;
}

void PosixTestClient::disconnect() const
{
	m_pClient->eDisconnect();

	printf ( "Disconnected\n");
}

bool PosixTestClient::isConnected() const
{
	return m_pClient->isConnected();
}

void PosixTestClient::processMessages()
{
	fd_set readSet, writeSet, errorSet;

	struct timeval tval;
	tval.tv_usec = 0;
	tval.tv_sec = 0;

	time_t now = time(NULL);
//	std::cout<< "Debug-- time now" << now <<std::endl;

	switch (m_state) {
		case ST_PLACEORDER:
			std::cout<<"Message: ST_Placeorder"<<std::endl;
			placeOrder();
			break;
		case ST_PLACEORDER_ACK:
			break;
		case ST_CANCELORDER:
			cancelOrder();
			break;
		case ST_CANCELORDER_ACK:
			break;
		case ST_PING:
			reqCurrentTime();
			break;
		case ST_PING_ACK:
			if( m_sleepDeadline < now) {
				disconnect();
				return;
			}
			break;
		case ST_REQHISTORICALDATA:
//						std::cout<<"Message: request historical data  babababa"<<std::endl;
			reqHistoricalData();
			m_state = ST_REQMARKETDATA;
			break;

		case ST_REQHISTORICALDATA_ACK:
			break;

		case ST_REQMARKETDATA:
//						std::cout<<"Message: request market data babababa"<<std::endl;
//			reqMktData();
			reqMktDataDell();
			reqMktDataAMD();
			break;

		case ST_REQMARKETDATA_ACK:
			break;

		case ST_IDLE:
			if( m_sleepDeadline < now) {
				m_state = ST_PING;
				return;
			}
			break;
	}



	if( m_sleepDeadline > 0) {
		// initialize timeout with m_sleepDeadline - now
		tval.tv_sec = m_sleepDeadline - now;
	}

	if( m_pClient->fd() >= 0 ) {

		FD_ZERO( &readSet);
		errorSet = writeSet = readSet;

		FD_SET( m_pClient->fd(), &readSet);

		if( !m_pClient->isOutBufferEmpty())
			FD_SET( m_pClient->fd(), &writeSet);

		FD_CLR( m_pClient->fd(), &errorSet);

		int ret = select( m_pClient->fd() + 1, &readSet, &writeSet, &errorSet, &tval);

		if( ret == 0) { // timeout
			return;
		}

		if( ret < 0) {	// error
			disconnect();
			return;
		}

		if( m_pClient->fd() < 0)
			return;

		if( FD_ISSET( m_pClient->fd(), &errorSet)) {
			// error on socket
			m_pClient->onError();
		}

		if( m_pClient->fd() < 0)
			return;

		if( FD_ISSET( m_pClient->fd(), &writeSet)) {
			// socket is ready for writing
			m_pClient->onSend();
		}

		if( m_pClient->fd() < 0)
			return;

		if( FD_ISSET( m_pClient->fd(), &readSet)) {
			// socket is ready for reading
			m_pClient->onReceive();
		}
	}
}

//////////////////////////////////////////////////////////////////
// methods
void PosixTestClient::reqCurrentTime()
{
	printf( "Requesting Current Time\n");

	// set ping deadline to "now + n seconds"
	m_sleepDeadline = time( NULL) + PING_DEADLINE;

	m_state = ST_PING_ACK;

	m_pClient->reqCurrentTime();
}

void PosixTestClient::placeOrder()
{
	Contract contract;
	Order order;

	contract.symbol = "MSFT";
	contract.secType = "STK";
	contract.exchange = "SMART";
	contract.currency = "USD";

	order.action = "BUY";
	order.totalQuantity = 1000;
	order.orderType = "LMT";
	order.lmtPrice = 29.00;

	printf( "Placing Order %ld: %s %ld %s at %f\n", m_orderId, order.action.c_str(), 
		order.totalQuantity, contract.symbol.c_str(), order.lmtPrice);

	m_state = ST_PLACEORDER_ACK;

	m_pClient->placeOrder( m_orderId, contract, order);
}


void PosixTestClient::placeOrderBuyDell()
{
	Contract contract;
	Order order;

	contract.symbol = "MSFT";
	contract.secType = "STK";
	contract.exchange = "SMART";
	contract.currency = "USD";

	order.action = "BUY";
	order.totalQuantity = 1000;
	order.orderType = "LMT";
	order.lmtPrice = 29.00;

	printf( "Placing Order %ld: %s %ld %s at %f\n", m_orderId, order.action.c_str(), 
		order.totalQuantity, contract.symbol.c_str(), order.lmtPrice);

	m_state = ST_PLACEORDER_ACK;

	m_pClient->placeOrder( m_orderId, contract, order);
}



void PosixTestClient::cancelOrder()
{
	printf( "Cancelling Order %ld\n", m_orderId);

	m_state = ST_CANCELORDER_ACK;

	m_pClient->cancelOrder( m_orderId);
}

void PosixTestClient::reqHistoricalData()
{
	Contract contract;
	Order order;

	contract.symbol = "EUR";
	contract.secType = "CASH";
	contract.exchange = "IDEALPRO";
	contract.currency = "USD";

	// See http://www.interactivebrokers.com/php/apiUsersGuide/apiguide/api/historical_data_limitations.htm#XREF_93621_Historical_Data
	// for limitations on historical data
	std::cout << "Requesting historical data" << std::endl;
	m_state = ST_REQHISTORICALDATA_ACK;
	m_pClient->reqHistoricalData(	m_orderId,				// a long int
									contract,				// a Contract object
									"20110102 00:00:00",	// a string in the format shown
									"6 W",					// a string saying how far back in time you want data
									"1 day",				// the bar size, i.e., how big a time chunk
									"BID",				// can also be bids, asks, volatility, other stuff
									1,						// 1="useRTH", other possibilities available
									1						// date format; 1=a standard date string 
								);
}

void PosixTestClient::reqMktDataDell() {
	// This is hardwired to request ticker data for Apple and Intel
	Contract contract;
	Order order;
	int orderId=100;

	contract.symbol = "DELL";
	contract.secType = "STK";
	contract.exchange = "SMART";
	contract.currency = "USD";
	std::cout << "Requesting market data for DELL" <<"OrderID="<<orderId<< std::endl;
	m_state = ST_REQMARKETDATA_ACK;

	m_pClient -> reqMktData(	orderId,				// a long int
								contract,				// the contract defined above
								"100",					// generic tick types, not relevant to stocks
								false					// snapshot?
							);

/*	contract.symbol = "AMD";
	std::cout << "Requesting market data for AMD" <<"OrderID="<<orderId+1<<std::endl;
	m_pClient -> reqMktData(	orderId+1,			// a long int
								contract,				// the contract just modified
								"100",					// generic tick types, not relevant to stocks
								false					// snapshot?
							);
							*/
}


void PosixTestClient::reqMktDataAMD() {
	// This is hardwired to request ticker data for Apple and Intel
	Contract contract;
	Order order;
	int orderId=101;


	contract.symbol = "AMD";
	contract.secType = "STK";
	contract.exchange = "SMART";
	contract.currency = "USD";
	std::cout << "Requesting market data for AMD" <<"OrderID="<<orderId<< std::endl;
	m_state = ST_REQMARKETDATA_ACK;

	m_pClient -> reqMktData(	orderId,				// a long int
								contract,				// the contract defined above
								"100",					// generic tick types, not relevant to stocks
								false					// snapshot?
							);

/*	contract.symbol = "AMD";
	std::cout << "Requesting market data for AMD" <<"OrderID="<<orderId+1<<std::endl;
	m_pClient -> reqMktData(	orderId+1,			// a long int
								contract,				// the contract just modified
								"100",					// generic tick types, not relevant to stocks
								false					// snapshot?
							);
							*/
}




///////////////////////////////////////////////////////////////////
// events
void PosixTestClient::orderStatus( OrderId orderId, const IBString &status, int filled,
	   int remaining, double avgFillPrice, int permId, int parentId,
	   double lastFillPrice, int clientId, const IBString& whyHeld)

{
	if( orderId == m_orderId) {
		if( m_state == ST_PLACEORDER_ACK && (status == "PreSubmitted" || status == "Submitted"))
			m_state = ST_CANCELORDER;

		if( m_state == ST_CANCELORDER_ACK && status == "Cancelled")
			m_state = ST_PING;

		printf( "Order: id=%ld, status=%s\n", orderId, status.c_str());
	}
}

void PosixTestClient::nextValidId( OrderId orderId)
{
	m_orderId = orderId;

	//m_state = ST_PLACEORDER;
	m_state = ST_REQMARKETDATA;
}

void PosixTestClient::currentTime( long time)
{
	if ( m_state == ST_PING_ACK) {
		time_t t = ( time_t)time;
		struct tm * timeinfo = localtime ( &t);
		printf( "The current date/time is: %s", asctime( timeinfo));

		time_t now = ::time(NULL);
		m_sleepDeadline = now + SLEEP_BETWEEN_PINGS;

		m_state = ST_IDLE;
	}
}

void PosixTestClient::error(const int id, const int errorCode, const IBString errorString)
{
	printf( "Error id=%d, errorCode=%d, msg=%s\n", id, errorCode, errorString.c_str());

	if( id == -1 && errorCode == 1100) // if "Connectivity between IB and TWS has been lost"
		disconnect();
}



void PosixTestClient::tickSize( TickerId tickerId, TickType field, int size) {}
void PosixTestClient::tickOptionComputation( TickerId tickerId, TickType tickType, double impliedVol, double delta,
											 double modelPrice, double pvDividend) {}

void PosixTestClient::tickGeneric(TickerId tickerId, TickType tickType, double value) {}
void PosixTestClient::tickString(TickerId tickerId, TickType tickType, const IBString& value) {}
void PosixTestClient::tickEFP(TickerId tickerId, TickType tickType, double basisPoints, const IBString& formattedBasisPoints,
							   double totalDividends, int holdDays, const IBString& futureExpiry, double dividendImpact, double dividendsToExpiry) {}
void PosixTestClient::openOrder( OrderId orderId, const Contract&, const Order&, const OrderState& ostate) {}
void PosixTestClient::openOrderEnd() {}
void PosixTestClient::winError( const IBString &str, int lastError) {}
void PosixTestClient::connectionClosed() {}
void PosixTestClient::updateAccountValue(const IBString& key, const IBString& val,
										  const IBString& currency, const IBString& accountName) {}
void PosixTestClient::updatePortfolio(const Contract& contract, int position,
		double marketPrice, double marketValue, double averageCost,
		double unrealizedPNL, double realizedPNL, const IBString& accountName){}
void PosixTestClient::updateAccountTime(const IBString& timeStamp) {}
void PosixTestClient::accountDownloadEnd(const IBString& accountName) {}
void PosixTestClient::contractDetails( int reqId, const ContractDetails& contractDetails) {}
void PosixTestClient::bondContractDetails( int reqId, const ContractDetails& contractDetails) {}
void PosixTestClient::contractDetailsEnd( int reqId) {}
void PosixTestClient::execDetails( int reqId, const Contract& contract, const Execution& execution) {}
void PosixTestClient::execDetailsEnd( int reqId) {}

void PosixTestClient::updateMktDepth(TickerId id, int position, int operation, int side,
									  double price, int size) {}
void PosixTestClient::updateMktDepthL2(TickerId id, int position, IBString marketMaker, int operation,
										int side, double price, int size) {}
void PosixTestClient::updateNewsBulletin(int msgId, int msgType, const IBString& newsMessage, const IBString& originExch) {}
void PosixTestClient::managedAccounts( const IBString& accountsList) {}
void PosixTestClient::receiveFA(faDataType pFaDataType, const IBString& cxml) {}

void PosixTestClient::scannerParameters(const IBString &xml) {}
void PosixTestClient::scannerData(int reqId, int rank, const ContractDetails &contractDetails,
	   const IBString &distance, const IBString &benchmark, const IBString &projection,
	   const IBString &legsStr) {}
void PosixTestClient::scannerDataEnd(int reqId) {}
void PosixTestClient::realtimeBar(TickerId reqId, long time, double open, double high, double low, double close,
								   long volume, double wap, int count) {}
void PosixTestClient::fundamentalData(TickerId reqId, const IBString& data) {}
void PosixTestClient::deltaNeutralValidation(int reqId, const UnderComp& underComp) {}
void PosixTestClient::tickSnapshotEnd(int reqId) {}

